Weighted Linear Fit

June 9, 2021

In this notebook we will fit a linear function to a set of experimental data. The fit will be weighted by the measurement uncertainties.

Updated by Jordan Andrews on June 9, 2021 with the use of np.polynomial.Polynomial([a, b, c]).

In this example, our data will be the voltage across and the current through a resistor. The slope of our data will tell us the resistance of the resistor. First import the NumPy module.

Enter the data as arrays.

When the data was collected the current was measured as rms values, convert the peak-to-peak voltage measurements to rms by dividing by $2\sqrt{2}$.

Notice that the current data has larger relative errors than the voltage data (typically by a factor of two or more):

Because the relative error in current is larger, we will plot the data as current vs voltage and show the error bars only along the y-axis. Use plt.errorbar(x,y,e) from the Matplotlib module.

To do the actual fit, we will use the 'curve_fit()' function from, the SciPy module. This way of fitting is very nice because we will be able to use it for all types of fit models (linear, polynomial, linear-in-parameter fits, and nonlinear fits). As we will see, it is capable of doing both unweighted and weighted fits and it will return uncertainties in the fit parameters.

The first step is to define a function for the model that we will fit our data to. In this case, the model is just the equation of a staight a line.

Here is the actual command to execute the fit. At a minimum, curve_fit() requires as inputs the function that defines the model, the $x$-data, and the $y$-data. The statement below tells curve_fit() to return a list of the the best-fit parameters (a_fit) and the covariance matrix (cov) which will be used to determine the error in the fit parameters.

Here are the contents of a_fit and cov.

As we will see in PHYS 232, the uncertainties of the best-fit parameters are determined from the square roots of the diagonal elements of the covariance matrix. We can select the diagonal elements using:

NumPy has a nice package for polynomials, called polynomial. There are six different polynomial types in this package. For our case, we are dealing with a simple power series. You can use thePolynomial constructor for this. y = np.polynomial.Polynomial([a, b, c]) results in $y = a + b\,x + c\,x^2$.

Here's the best-fit fucntion obtained using a_fit from curve_fit() and the built in polynomial package of NumPy.

We can then evaluate fitFcn(x) at any value of $x$ that we want.

This gives us an easy way to plot the fit on top of the data.

All of this has produced an "unweighted" fit to the data. To include weights, all we need to do is include another option in curve_fit(). Everything else is exactly the same! The new option is sigma and it is simply a list of the errors in the $y$-values. Note that many fitting routines require you to provide the actual weights as $1/\sigma^2$. That is not the case here. You just have to provide the absolute $y$-uncertainties.

Extract the fit parameters and their uncertainties.

Get the best-fit line.

Plot the data...

Save the plot as a pdf.